package com.flyqiu.common.tools;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.flyqiu.common.exception.file.FlyQiuFileNotFoundException;
import com.flyqiu.common.exception.file.FlyQiuPathNotIsFile;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * 文件工具类，提供文件读写和JSON解析功能。
 */
public class FlyQiuFileTools {

    /**
     * 保存文件。
     *
     * @param file    文件
     * @param content 文件内容
     */
    public static void saveFile(File file, String content) {
        saveFile(file, content, StandardCharsets.UTF_8);
    }

    /**
     * 保存文件。
     *
     * @param file    文件
     * @param content 文件内容
     * @param charset 文件编码
     */
    public static void saveFile(File file, String content, Charset charset) {
        saveFile(file, content.getBytes(charset));
    }

    /**
     * 保存文件。
     *
     * @param file  文件
     * @param bytes 文件内容
     */
    public static void saveFile(File file, byte[] bytes) {
        try {
            // 创建父目录
            if (!file.exists()) {
                File parentFile = file.getParentFile();
                if (!parentFile.exists()) {
                    parentFile.mkdirs();
                }
                file.createNewFile();
            }
            try (FileOutputStream fileOutputStream = new FileOutputStream(file)) {
                fileOutputStream.write(bytes);
                fileOutputStream.flush();
            }
        } catch (IOException e) {
            throw new RuntimeException("保存文件失败", e);
        }
    }

    /**
     * 获取文件内容。
     *
     * @param filePath 文件路径
     * @return 文件内容
     */
    public static byte[] getFileContent(String filePath) {
        return getFileContent(new File(filePath));
    }

    /**
     * 获取文件内容。
     *
     * @param file 文件
     * @return 文件内容
     */
    public static byte[] getFileContent(File file) {
        if (!file.exists()) {
            throw new FlyQiuFileNotFoundException(file);
        }
        if (file.isDirectory()) {
            throw new FlyQiuPathNotIsFile(file);
        }
        try (FileInputStream fileInputStream = new FileInputStream(file)) {
            return readInputStream(fileInputStream);
        } catch (IOException e) {
            throw new RuntimeException("读取文件失败", e);
        }
    }

    /**
     * 读取输入流。
     *
     * @param inputStream 输入流
     * @return 输入流内容
     * @throws IOException IO异常
     */
    private static byte[] readInputStream(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[1024];
        int len = 0;
        try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
            while ((len = inputStream.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
            }
            return bos.toByteArray();
        }
    }

    /**
     * 读取输入流并转换为字符串。
     *
     * @param inputStream 输入流
     * @param charset     文件编码
     * @return 输入流内容
     */
    public static String readInputStream(InputStream inputStream, Charset charset) {
        try {
            byte[] bytes = readInputStream(inputStream);
            return new String(bytes, charset);
        } catch (IOException e) {
            throw new RuntimeException("读取输入流失败", e);
        }
    }

    /**
     * 读取文件内容。
     *
     * @param filePath 文件路径
     * @return 文件内容
     */
    public static String getFileContentByString(String filePath) {
        return getFileContentByString(filePath, StandardCharsets.UTF_8);
    }

    /**
     * 读取文件内容。
     *
     * @param filePath 文件路径
     * @param charset  文件编码
     * @return 文件内容
     */
    public static String getFileContentByString(String filePath, Charset charset) {
        byte[] fileContent = getFileContent(new File(filePath));
        return new String(fileContent, charset);
    }

    /**
     * 读取文件内容。
     *
     * @param file 文件
     * @return 文件内容
     */
    public static String getFileContentByString(File file) {
        return getFileContentByString(file, StandardCharsets.UTF_8);
    }

    /**
     * 读取文件内容。
     *
     * @param file    文件
     * @param charset 文件编码
     * @return 文件内容
     */
    public static String getFileContentByString(File file, Charset charset) {
        byte[] fileContent = getFileContent(file);
        return new String(fileContent, charset);
    }

    /**
     * 读取文件内容并转换为JSON对象。
     *
     * @param file 文件
     * @return JSON对象
     */
    public static JSONObject readFileToJsonObject(File file) {
        return readFileToJsonObject(file, StandardCharsets.UTF_8);
    }

    /**
     * 读取文件内容并转换为JSON对象。
     *
     * @param file    文件
     * @param charset 文件编码
     * @return JSON对象
     */
    public static JSONObject readFileToJsonObject(File file, Charset charset) {
        String fileContent = getFileContentByString(file, charset);
        return JSONObject.parseObject(fileContent);
    }

    /**
     * 读取文件内容并转换为JSON对象。
     *
     * @param filePath 文件路径
     * @return JSON对象
     */
    public static JSONObject readFileToJsonObject(String filePath) {
        String fileContent = getFileContentByString(filePath, StandardCharsets.UTF_8);
        return JSONObject.parseObject(fileContent);
    }

    /**
     * 读取文件内容并转换为JSON对象。
     *
     * @param filePath 文件路径
     * @param charset  文件编码
     * @return JSON对象
     */
    public static JSONObject readFileToJsonObject(String filePath, Charset charset) {
        String fileContent = getFileContentByString(filePath, charset);
        return JSONObject.parseObject(fileContent);
    }

    /**
     * 读取文件内容并转换为JSON数组。
     *
     * @param file 文件
     * @return JSON数组
     */
    public static JSONArray readFileToJsonArray(File file) {
        return readFileToJsonArray(file, StandardCharsets.UTF_8);
    }

    /**
     * 读取文件内容并转换为JSON数组。
     *
     * @param file    文件
     * @param charset 文件编码
     * @return JSON数组
     */
    public static JSONArray readFileToJsonArray(File file, Charset charset) {
        String fileContent = getFileContentByString(file, charset);
        return JSONArray.parseArray(fileContent);
    }

    /**
     * 读取文件内容并转换为JSON数组。
     *
     * @param filePath 文件路径
     * @return JSON数组
     */
    public static JSONArray readFileToJsonArray(String filePath) {
        String fileContent = getFileContentByString(filePath, StandardCharsets.UTF_8);
        return JSONArray.parseArray(fileContent);
    }

    /**
     * 读取文件内容并转换为JSON数组。
     *
     * @param filePath 文件路径
     * @param charset  文件编码
     * @return JSON数组
     */
    public static JSONArray readFileToJsonArray(String filePath, Charset charset) {
        String fileContent = getFileContentByString(filePath, charset);
        return JSONArray.parseArray(fileContent);
    }

    /**
     * 读取文件内容并转换为JSON对象列表。
     *
     * @param filePath 文件路径
     * @return JSON对象列表
     */
    public static List<JSONObject> readFileToListJson(String filePath) {
        String fileContent = getFileContentByString(filePath, StandardCharsets.UTF_8);
        return readFileToList(filePath, JSONObject.class);
    }

    /**
     * 读取文件内容并转换为指定类型的列表。
     *
     * @param filePath 文件路径
     * @param clazz    类型
     * @param <T>      泛型类型
     * @return 指定类型的列表
     */
    public static <T> List<T> readFileToList(String filePath, Class<T> clazz) {
        String fileContent = getFileContentByString(filePath, StandardCharsets.UTF_8);
        return JSONArray.parseArray(fileContent).toList(clazz);
    }
}
